home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Reference Guide
/
C-C++ Interactive Reference Guide.iso
/
c_ref
/
csource5
/
308_01
/
rmezloop.c
< prev
next >
Wrap
Text File
|
1990-06-18
|
23KB
|
814 lines
/* FILE RMEZLOOP.C */
/* 7 October 1989 */
/* Remez Exchange FIR Filter Design Program
/* Translated into C by Bob Briggs
/* Based on FORTRAN program by Parks McClellan as
/* listed in Prentice Hall book by Rabiner & Gold
/* "Theory and Application of Digital Signal Processing"
/* and BASIC translation by N. Loy in Prentice Hall book
/* "An Engineer's Guide to FIR Digital Filters"
/* Writes file "impulse.rmz"
/* For $5 I will send a copy of a hand drawn flowchart
/* showing the loops in the "remez" function.
/* Bob Briggs
/* 1337 Rossway Ct.
/* Los Altos, CA 94024
*/
#include <stdio.h>
#include <math.h>
#define PI (3.141592653589793)
#define PI2 (6.283185307179586)
#define NFMAX (128) /* maximum filter length */
#define EPS (1e-24) /* small number */
#define ITRMAX (25) /* maximum number of iterations */
#define NBMAX (10) /* maximum number of bands */
int nfcns,ngrid;
int iext[(NFMAX/2+2)+1];
double alpha[(NFMAX/2+2)+1],des[16*(NFMAX/2+2)+1];
double grid[16*(NFMAX/2+2)+1];
double wt[16*(NFMAX/2+2)+1];
double dev;
double ad[(NFMAX/2+2)+1],x[(NFMAX/2+2)+1],y[(NFMAX/2+2)+1];
main(){
void rerror(),exit(),remez();
int i,j,k,l;
int keyboard, example1, example2, example3, example4;
int jtype,kup,lband,lgrid,nfilt,nbands,result;
int jb,neg,nodd,nm1,nz;
double delf,fup,temp,change;
double d(),gee();
double deviat[NBMAX+1],wtx[NBMAX+1];
double edge[2*NBMAX+1],fx[NBMAX+1],h[(NFMAX/2+2)+1];
FILE *chan;
jtype = 0;
keyboard = 0;
example1 = 0;
example2 = 0;
example3 = 0;
example4 = 0;
printf(" ... REMEZ EXCHANGE FIR FILTER DESIGN PROGRAM ... \n");
putchar('\n');
result = 0;
while(!result){
printf("Select 1 to 5: --- then press ENTER\n");
printf("1: EXAMPLE1 --- LOWPASS FILTER\n");
printf("2: EXAMPLE2 --- BANDPASS FILTER\n");
printf("3: EXAMPLE3 --- DIFFERENTIATOR\n");
printf("4: EXAMPLE4 --- HILBERT TRANSFORMER\n");
printf("5: KEYBOARD --- GET INPUT PARAMETERS FROM KEYBOARD\n");
putchar('\n');
result = scanf("%d",&i);
switch(i){
case 1: example1 = 1;
break;
case 2: example2 = 1;
break;
case 3: example3 = 1;
break;
case 4: example4 = 1;
break;
case 5: keyboard = 1;
break;
default: result = 0;
}
}
if(keyboard){ /* GET DATA FROM KEYBOARD */
printf("Filter types are: 1=Bandpass, 2=Differentiator, 3=Hilbert\n");
/* GET INPUT DATA FROM USER */
printf("Input: # coeff, Filter type, # bands, Grid density\n");
printf("Use tab, space, or return to separate each input ...\n");
result = scanf("%d%d%d%d",&nfilt,&jtype,&nbands,&lgrid);
putchar('\n');
putchar('\n');
printf("Band and edge (corner) definition:\n");
putchar('\n');
printf("Edge #: 1 2 3 4 5 6\n");
printf("Band #: 1 2 3\n");
printf(" | -------\n");
printf(" | * *\n");
printf(" Mag | * *\n");
printf(" | * *\n");
printf(" |----- -------------\n");
printf(" |_______________________________\n");
printf(" Frequency\n");
jb = 2 * nbands;
printf("Now inputting edge (corner) frequencies for %d band edges\n",jb);
for(i=1;i<=jb;i++){
printf("Input edge frequency for edge (corner) # %d:\n",i);
result = scanf("%lf",&edge[i]); /* lf = long float = double */
}
for(i=1;i<=nbands;i++){
printf("Input gain, weight of band # %d:",i);
result = scanf("%lf%lf",&fx[i],&wtx[i]);
putchar('\n');
}
} /* end if(keyboard) */
else if(example1){ /* LOWPASS FILTER */
nfilt = 24;
jtype = 1;
nbands = 2;
lgrid = 16;
edge[1] = 0;
edge[2] = 0.08;
edge[3] = 0.16;
edge[4] = 0.5;
fx[1] = 1;
fx[2] = 0;
wtx[1] = 1;
wtx[2] = 1;
}
else if(example2){ /* BANDPASS FILTER */
nfilt = 32;
jtype = 1;
nbands = 3;
lgrid = 16;
edge[1] = 0;
edge[2] = 0.1;
edge[3] = 0.2;
edge[4] = 0.35;
edge[5] = 0.425;
edge[6] = 0.5;
fx[1] = 0;
fx[2] = 1;
fx[3] = 0;
wtx[1] = 10;
wtx[2] = 1;
wtx[3] = 10;
}
else if(example3){ /* DIFFERENTIATOR */
nfilt = 32;
jtype = 2;
nbands = 1;
lgrid = 16;
edge[1] = 0;
edge[2] = 0.5;
fx[1] = 1;
wtx[1] = 1;
}
else if(example4){ /* HILBERT TRANSFORMER */
nfilt = 20;
jtype = 3;
nbands = 1;
lgrid = 16;
edge[1] = 0.05;
edge[2] = 0.5;
fx[1] = 1;
wtx[1] = 1;
}
/* END INPUT DATA SECTION */
if(nfilt > NFMAX){
printf("Error: # coeff > %d\n...now exiting to system...\n",NFMAX);
exit(1);
}
if(nfilt < 3) rerror("Error: # coeff < 3");
if(nbands <= 0) nbands = 1;
if(lgrid <= 0) lgrid = 16;
printf("#coeff = %d\nType = %d\n#bands = %d\nGrid = %d\n",
nfilt,jtype,nbands,lgrid);
for(i=1;i<=2*nbands;i++) printf("E[%d] = %.2lf\n",i,edge[i]);
for(i=1;i<=nbands;i++) printf("Gain, wt[%d] = %.2lf %.2lf\n",i,fx[i],wtx[i]);
putchar('\n');
if(jtype == 0) rerror("Filter type = 0 not valid\n");
neg = 1;
if(jtype == 1) neg = 0;
nodd = nfilt % 2;
nfcns = nfilt / 2;
if(nodd == 1 && neg == 0) nfcns++;
/* SET UP THE DENSE GRID. THE NUMBER OF POINTS IN THE GRID
/* IS (FILTER LENGTH + 1)*GRID DENSITY/2 */
grid[1] = edge[1];
delf = lgrid * nfcns;
delf = 0.5/delf;
if(neg != 0 && edge[1] < delf) grid[1] = delf;
/* CALCULATE THE DESIRED MAGNITUDE RESPONSE AND THE WEIGHT
/* FUNCTION ON THE GRID */
j = 1;
l = 1;
lband = 1;
while(1){ /* loop until break */
fup = edge[l+1];
do{
temp = grid[j];
des[j] = fx[lband];
if(jtype == 2) des[j] *= temp;
wt[j] = wtx[lband];
if(jtype == 2 && fx[lband] >= 0.0001) wt[j] /= temp;
j++;
grid[j] = temp + delf;
}while(grid[j] <= fup);
grid[j-1] = fup;
des[j-1] = fx[lband];
if(jtype == 2) des[j-1] *= fup;
wt[j-1] = wtx[lband];
if(jtype == 2 && fx[lband] >= 0.0001) wt[j-1] /= fup;
lband++;
l += 2;
if(lband > nbands) break;
grid[j] = edge[l];
} /* END while(1) */
ngrid = j-1;
if(neg == nodd && grid[ngrid] > (0.5 - delf)) ngrid--;
/* SET UP A NEW APPROXIMATION PROBLEM WHICH IS EQUIVALENT
/* TO THE ORIGINAL PROBLEM */
if(neg <= 0){
if(nodd == 1); /* DO NOTHING */
else{
for(j=1;j <= ngrid;j++){
change = cos(PI * grid[j]);
if(change == 0) change = EPS;
des[j] /= change;
wt[j] *= change;
}
}
}
else{
if(nodd == 1){
for(j=1;j <= ngrid;j++){
change = sin(PI2 * grid[j]);
if(change == 0) change = EPS;
des[j] /= change;
wt[j] *= change;
}
}
else{
for(j=1;j <= ngrid;j++){
change = sin(PI * grid[j]);
if(change == 0) change = EPS;
des[j] /= change;
wt[j] *= change;
}
}
}
/* INITIAL GUESS FOR THE EXTREMAL FREQUENCIES -- EQUALLY
/* SPACED ALONG THE GRID */
temp = (ngrid - 1)/nfcns;
for(j=1;j<=nfcns;j++) iext[j] = (j-1) * temp + 1;
iext[nfcns+1] = ngrid;
nm1 = nfcns - 1;
nz = nfcns + 1;
/* CALL THE REMEZ EXCHANGE ALGORITHM TO DO THE APPROXIMATION PROBLEM */
remez(edge,nbands);
if(neg <= 0){
if(nodd == 0){
h[1] = 0.25 * alpha[nfcns];
for(j=2;j<=nm1;j++)
h[j] = 0.25 * (alpha[nz - j] + alpha[nfcns + 2 - j]);
h[nfcns] = 0.5 * alpha[1] + 0.25 * alpha[2];
}
else{
for(j=1;j<=nm1;j++) h[j] = 0.5 * alpha[nz - j];
h[nfcns] = alpha[1];
}
}
else{
if(nodd == 0){
h[1] = 0.25 * alpha[nfcns];
for(j=2;j<=nm1;j++)
h[j] = 0.25 * (alpha[nz - j] - alpha[nfcns + 2 - j]);
h[nfcns] = 0.5 * alpha[1] - 0.25 * alpha[2];
}
else{
h[1] = 0.25 * alpha[nfcns];
h[2] = 0.25 * alpha[nm1];
for(j=3;j<=nm1;j++)
h[j] = 0.25 * (alpha[nz-j] - alpha[nfcns + 3 - j]);
h[nfcns] = 0.5 * alpha[1] - 0.25 * alpha[3];
h[nz] = 0.0;
}
}
/* PROGRAM OUTPUT SECTION */
putchar('\n');
for(j=1;j<=70;j++) putchar('*');
putchar('\n');
printf(" FINITE IMPULSE RESPONSE (FIR)\n");
printf(" LINEAR PHASE DIGITAL FILTER DESIGN\n");
printf(" REMEZ EXCHANGE ALGORITHM\n");
switch(jtype){
case 1: printf(" BANDPASS FILTER\n");
break;
case 2: printf(" DIFFERENTIATOR\n");
break;
case 3: printf(" HILBERT TRANSFORMER\n");
break;
}
printf(" FILTER LENGTH = %d\n",nfilt);
printf(" ***** IMPULSE RESPONSE *****\n");
for(j=1;j<=nfcns;j++){
k = nfilt + 1 - j;
if(neg == 0)
printf(" H(%3d) = %15.9e = H(%4d)\n",j,h[j],k);
if(neg == 1)
printf(" H(%3d) = %15.9e = -H(%4d)\n",j,h[j],k);
}
if(neg == 1 && nodd == 1)
printf(" H(%3d) = 0.0\n",nz); /* nz = nfcns + 1 */
putchar('\n');
for(k=1;k<=nbands;k+=4){
kup = k + 3;
if(kup > nbands) kup = nbands;
for(j=1;j<=23;j++) putchar(' ');
for(j=k;j<=kup;j++) printf("BAND%2d ",j);
putchar('\n');
printf(" LOWER BAND EDGE");
for(j=k;j<=kup;j++) printf("%15.8f",edge[2*j-1]);
putchar('\n');
printf(" UPPER BAND EDGE");
for(j=k;j<=kup;j++) printf("%15.8f",edge[2*j]);
putchar('\n');
if(jtype != 2){
printf(" DESIRED VALUE ");
for(j=k;j<=kup;j++) printf("%15.8f",fx[j]);
putchar('\n');
}
if(jtype == 2){
printf(" DESIRED SLOPE ");
for(j=k;j<=kup;j++) printf("%15.8f",fx[j]);
putchar('\n');
}
printf(" WEIGHTING ");
for(j=k;j<=kup;j++) printf("%15.8f",wtx[j]);
putchar('\n');
for(j=k;j<=kup;j++) deviat[j] = dev/wtx[j];
printf(" DEVIATION ");
for(j=k;j<=kup;j++) printf("%15.8f",deviat[j]);
putchar('\n');
if(jtype != 1) continue;
for(j=k;j<=kup;j++) deviat[j] = 20.0 * log10(deviat[j]);
printf(" DEVIATION IN DB");
for(j=k;j<=kup;j++) printf("%15.8f",deviat[j]);
putchar('\n');
}
putchar('\n');
printf(" EXTREMAL FREQUENCIES\n");
putchar(' ');
for(j=1;j<=nz;j++){
printf("%12.7f",grid[iext[j]]);
if(!(j%5)){ putchar('\n');putchar(' ');} /* CR every 5 columns */
}
putchar('\n');
for(j=1;j<=70;j++) putchar('*');
putchar('\n');
/* NOW WRITE DATA TO FILE "IMPULSE.RMZ" */
chan = fopen("impulse.rmz","wb"); /* opens file for write binary */
if(chan == 0){printf("Cannot open file %s\n","impulse.rmz");exit();}
for(j=1;j<=nfcns;j++){
fprintf(chan,"%f ",h[j]);
if(!(j%4)){fputc('\r',chan);fputc('\n',chan);} /* CRLF every 4 values */
}
if(neg == 1 && nodd == 1) fprintf(chan,"0.0 ");
for(j=nfcns;j>=1;j--){
if(neg == 0) fprintf(chan,"%f ",h[j]);
if(neg == 1) fprintf(chan,"%f ",-h[j]);
if(!((nfcns-j+1)%4)){fputc('\r',chan);fputc('\n',chan);}
/* CRLF every 4 values */
}
fclose(chan);
} /* END main() */
/* REMEZ EXCHANGE ALGORITHM */
void remez(edge,nbands) double edge[];int nbands;{
int j,k,l;
int jchnge,jet,jm1,jp1;
int k1,kkk,klow,kn,knz,kup;
int loop1,luck;
int niter,nm1,nu,nut,nut1,nz,nzz;
int out1,out2,out3;
double cn,fsh,gtemp;
double delf,tmp;
double devl,dtemp,dnum,dden,err;
double comp,y1,ynz,aa,bb,ft,xt,xe;
double d(),gee();
double a[67],p[67],q[67];
devl = -1.0;
nz = nfcns + 1;
nzz = nfcns + 2;
niter = 0;
comp = 0;
luck = 0;
y1 = 0;
nut1 = 0;
loop1 = 1;
printf("Iteration");
while(niter++ < ITRMAX){ /* LOOP 1 */
if(loop1 == 0) break; /* OUT OF LOOP1 */
printf(" %d",niter);
if(!(niter%20)) putchar('\n'); /* newline every 20 iterations */
iext[nzz] = ngrid + 1;
for(j=1;j<=nz;j++) x[j] = cos(PI2 * grid[iext[j]]);
jet = (int)((nfcns - 1)/15 +1);
for(j=1;j<=nz;j++) ad[j] = d(j,nz,jet);
dnum = 0.0;
dden = 0.0;
k=1;
for(j=1;j<=nz;j++){
l=iext[j];
dnum += ad[j] * des[l];
if(wt[l] == 0.0) wt[l] = EPS;
dden += k*ad[j]/wt[l];
k = -k;
}
dev = dnum/dden;
nu = 1;
if(dev > 0.0) nu = -1;
dev *= -nu;
k = nu;
for(j=1;j<=nz;j++){
l = iext[j];
if(wt[l] == 0.0) wt[l] = EPS;
y[j] = des[l] + k*dev/wt[l];
k = -k;
}
if(dev < devl){ /* "ouch" */
printf(" ********* FAILURE TO CONVERGE **********\n");
printf("Probable cause is machine rounding error\n");
printf("The impulse response may be correct\n");
printf("Check with frequency response\n");
break; /* OUT OF LOOP 1 */
}
devl = dev;
jchnge = 0;
k1 = iext[1];
knz = iext[nz];
klow = 0;
nut = -nu;
j = 1;
/* SEARCH FOR THE EXTREMAL FREQUENCIES OF THE BEST APPROXIMATION */
while(1){ /* LOOP 2 */
if(j == nzz) ynz = comp;
if(j >= nzz){
if(j > nzz){
if(luck > 9){
kn = iext[nzz];
for(j=1;j<=nfcns;j++) iext[j] = iext[j+1];
iext[nz] = kn;
break; /* OUT OF LOOP 2 */
}
else{
if(comp > y1) y1 = comp;
k1 = iext[nzz];
lable325: l = ngrid + 1; /* label325 ? */
klow = knz;
nut = -nut1;
comp = y1 * (1.00001);
out1 = 0;
out2 = 0;
while(1){ /* LOOP 3 */
l--;
if(l <= klow){
out1 = 1;
break; /* out of LOOP 3 */
}
else{
err = (gee(l,nz) - des[l]) * wt[l];
dtemp = nut * err - comp;
if(dtemp > 0.0){ /* BREAK OUT OF LOOP 3 */
out2 = 1;
break; /* out of LOOP 3 */
}
}
} /* END OF while LOOP 3 */
if(out1){
if(luck == 6){
if(jchnge > 0) break; /* OUT OF LOOP 2 */
loop1 = 0;
break; /* OUT OF LOOP 2 and LOOP 1 */
}
for(j=1;j<=nfcns;j++) iext[nzz - j] = iext[nz - j];
iext[1] = k1;
break; /* OUT OF LOOP 2 */
} /* END OF if(out1) */
if(out2){
j = nzz;
comp = nut * err;
luck += 10;
goto lable235;
}
} /* END OF if(luck > 9) else */
} /* END OF if(j > nzz) */
else{
if(k1 > iext[1]) k1 = iext[1];
if(knz < iext[nz]) knz = iext[nz];
nut1 = nut;
nut = -nu;
l = 0;
kup = k1;
comp = ynz * (1.00001);
luck = 1;
out1 = 0;
out2 = 0;
while(1){ /* LOOP 4 */
l++;
if(l >= kup){
out1 = 1;
break; /* out of LOOP 4 */
}
err = (gee(l,nz) - des[l]) * wt[l];
dtemp = nut * err - comp;
if(dtemp > 0.0){ /* BREAK OUT OF LOOP 4 */
out2 = 1;
break; /* out of LOOP 4 */
}
} /* END OF while LOOP 4 */
if(out1){
luck = 6;
goto lable325;
}
if(out2){
j = nzz;
comp = nut * err;
goto lable210;
}
} /* END OF if(j > nzz) else */
} /* END OF if(j >= nzz) */
else{
kup = iext[j+1];
l = iext[j] + 1;
nut = - nut;
if(j == 2) y1 = comp;
comp = dev;
if(l >= kup){
lable220: l--;
out1 = 0;
out2 = 0;
out3 = 0;
while(1){ /* LOOP 5 */
l--;
if(l <= klow){
out1 = 1;
break; /* OUT OF LOOP 5 */
}
err = (gee(l,nz) - des[l]) * wt[l];
dtemp = nut * err - comp;
if(dtemp > 0.0){
out2 = 1;
break; /* OUT OF LOOP 5 */
}
if(jchnge > 0){
out3 = 1;
break; /* OUT OF LOOP5 */
}
} /* END OF while LOOP 5 */
if(out1){ /* if we exited LOOP 5 this way */
l = iext[j] + 1;
if(jchnge > 0){
iext[j] = l - 1;
j++;
klow = l - 1;
jchnge++;
continue; /* to top of LOOP 2 */
}
out1 = 0;
out2 = 0;
while(1){ /* LOOP 6 */
l++;
if(l >= kup){
out1 = 1;
break; /* OUT OF LOOP 6 */
}
err = (gee(l,nz) - des[l]) * wt[l];
dtemp = nut * err - comp;
if(dtemp > 0.0){ /* BREAK OUT OF LOOP 6 */
comp = nut * err;
out2 = 1;
break; /* OUT OF LOOP 6 */
}
} /* END OF while LOOP 6 */
if(out1){
klow = iext[j];
j++;
continue; /* to top of LOOP 2 */
}
if(out2) goto lable210;
} /* END OF if(out1) */
else if(out2){
comp = nut * err;
lable235: while(1){ /* LOOP 7 */
l--;
if(l <= klow) break; /* OUT OF LOOP 7 */
err = (gee(l,nz) - des[l]) * wt[l];
dtemp = nut * err - comp;
if(dtemp <= 0.0) break; /* OUT OF LOOP 7 */
comp = nut * err;
} /* END OF while LOOP 7 */
klow = iext[j];
iext[j] = l+1;
j++;
jchnge++;
continue; /* to top of LOOP 2 */
} /* END OF else if(out2) */
else if(out3){
klow = iext[j];
j++;
continue; /* to top of LOOP 2 */
}
} /* END OF if(l >= kup) */
else{
err = (gee(l,nz) - des[l]) * wt[l];
dtemp = nut * err - comp;
if(dtemp <= 0.0) goto lable220;
comp = nut * err;
lable210: while(1){ /* LOOP 8 */
l++;
if(l >= kup) break; /* OUT OF LOOP 8 */
err = (gee(l,nz) - des[l]) * wt[l];
dtemp = nut * err - comp;
if(dtemp <= 0.0) break; /* OUT OF LOOP 8 */
comp = nut * err;
}
iext[j] = l - 1;
j++;
klow = l - 1;
jchnge++;
continue; /* to top of LOOP 2 */
}
} /* END OF if(j >= nzz) else */
} /* END OF while LOOP 2 */
} /* END OF while LOOP 1 */
/* CALCULATION OF THE COEFFICIENTS OF THE BEST APPROXIMATION
/* USING THE INVERSE DISCRETE FOURIER TRANSFORM */
lable400:
nm1 = nfcns - 1;
fsh = 1.0e-6;
gtemp = grid[1];
x[nzz] = -2.0;
cn = 2 * nfcns - 1;
delf = 1.0 / cn;
l = 1;
kkk = 0;
if(edge[1] < 0.01 && edge[2*nbands] > 0.49) kkk = 1;
if(nfcns <= 3) kkk = 1;
if(kkk != 1) {
dtemp = cos(PI2 * grid[1]);
dnum = cos(PI2 * grid[ngrid]);
tmp = dtemp - dnum;
if(tmp == 0.0) tmp = EPS;
aa = 2.0/tmp;
bb = -(dtemp + dnum)/tmp;
}
for(j=1;j<=nfcns;j++){
ft = (j - 1) * delf;
xt = cos(PI2 * ft);
if(kkk != 1){
xt = (xt - bb)/aa;
ft = acos(xt)/PI2;
}
out1 = 0;
out2 = 0;
while(1){ /* LOOP 9 */
xe = x[l];
if(xt > xe){
out1 = 1;
break; /* OUT OF LOOP 9 */
}
if((xe - xt) < fsh){
out2 = 1;
break; /* OUT OF LOOP 9 */
}
l++;
} /* END OF while LOOP 9 */
if(out1){
if((xt - xe) < fsh) a[j] = y[l];
else{
grid[1] = ft;
a[j] = gee(1,nz);
}
}
if(out2) a[j] = y[l];
if(l > 1) l--;
} /* END for() LOOP */
grid[1] = gtemp;
dden = PI2/cn;
for(j=1;j<=nfcns;j++){
dtemp = 0.0;
dnum = (j-1) * dden;
if(nm1 >= 1) for(k=1;k<=nm1;k++)
dtemp += a[k+1] * cos(dnum * k);
alpha[j] = 2 * dtemp + a[1];
} /* END for() LOOP */
for(j=2;j<=nfcns;j++) alpha[j] *= 2/cn;
alpha[1] /= cn;
if(kkk != 1){
p[1] = 2.0 * alpha[nfcns] * bb + alpha[nm1];
p[2] = 2.0 * alpha[nfcns] * aa;
q[1] = alpha[nfcns - 2] - alpha[nfcns];
for(j=2;j<=nm1;j++){
if(j >= nm1){
aa *= 0.5;
bb *= 0.5;
}
p[j+1] = 0.0;
for(k=1;k<=j;k++){
a[k] = p[k];
p[k] = 2.0 * bb * a[k];
}
p[2] += 2.0 * aa * a[1];
jm1 = j-1;
for(k=1;k<=jm1;k++) p[k] += q[k] + aa * a[k+1];
jp1 = j + 1;
for(k=3;k<=jp1;k++) p[k] += aa * a[k-1];
if(j != nm1){
for(k=1;k<=j;k++) q[k] = - a[k];
q[1] += alpha[nfcns - 1 - j];
}
} /* END OF for() LOOP */
for(j=1;j<=nfcns;j++) alpha[j] = p[j];
} /* END OF if(kkk != 1) */
if(nfcns <= 3){
alpha[nfcns + 1] = 0.0;
alpha[nfcns + 2] = 0.0;
}
} /* END REMEZ EXCHANGE ALGORITHM */
/* FUNCTION TO CALCULATE THE LAGRANGE INTERPOLATION
/* COEFFICIENTS FOR USE IN THE FUNCTION GEE */
double d(k,n,m) int k,n,m;{
int j,el;
double de,q;
de = 1.0;
q = x[k];
for(el=1;el<=m;el++)
for(j=el;j<=n;j+=m)
if(j != k) de *= 2.0 * (q - x[j]);
if(de == 0.0) de = EPS;
return(1.0/de);
}
/* FUNCTION TO EVALUATE THE FREQUENCY RESPONSE USING THE
/* LAGRANGE INTERPOLATION FORMULA IN THE BARYCENTRIC FORM */
double gee(k,n) int k,n;{
int j;
double c,de,p,xf;
de = 0.0;
p = 0.0;
xf = cos(PI2*grid[k]);
for(j=1;j<=n;j++){
c = xf - x[j];
if(c == 0.0) c = EPS;
c = ad[j]/c;
de += c;
p += c * y[j];
}
if(de == 0.0) de = EPS;
return(p/de);
}
void rerror(error_text) char error_text[];{
void exit();
printf("%s\n",error_text);
printf("...now exiting to system...\n");
exit(1);
}